#!/usr/bin/env bash
str_pos(){
    if [[ ${#1} -lt ${#2} ]]; then
        echo -1
        return
    fi
    rest=${1#*${2}}
    if [[ $1 == $rest ]]; then
        echo -1
        return
    fi
    echo $(( ${#1} - ${#rest} - ${#2}))
}

postcss(){
    cat <<-EOF > postcss.config.js
module.exports = {
    plugins:[require('autoprefixer')]
}
EOF
}

packageFile(){
    cat <<-EOF > package.json
{
  "scripts": {
    "build": "ENV=production webpack --config webpack.config.js",
    "dev": "ENV=development webpack-dev-server --config webpack.config.js"
  }
}
EOF
}

reactOnly(){
    if [[ "$1" == "react" ]] ;then 
        echo $2
    fi
}

serverJs(){
    cat <<-EOF > server.js
//process.env.ENV
JSON.stringify()
module.exports = {
    path:'dist',
    port: 3000,
    publicPath : "", //公共目录
    eslint : false,   //是否开启eslint
    entry:['index'], //多入口配置
    proxy: {
        // '/api': {
        //   target: 'http://localhost:8080',
        //   changeOrigin: true
        // }
    },
    resolve:{
        extensions:['.js']
    } 
}    
EOF
}

install_webpack(){
    postcss
    serverJs
    packageFile
    echo "{}" > .eslintrc.json
    mkdir -p "src"
    touch "src/index.js"
    touch "src/index.html"

    cnpm install --save \
    @babel/runtime @babel/plugin-transform-runtime @babel/polyfill

    # npm install
    cnpm install \
    webpack \
    webpack-cli \
    html-webpack-plugin \
    style-loader \
    css-loader \
    less \
    less-loader \
    mini-css-extract-plugin \
    postcss-loader \
    autoprefixer \
    uglifyjs-webpack-plugin \
    optimize-css-assets-webpack-plugin \
    babel-loader @babel/core @babel/preset-env \
    @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties \
    @babel/plugin-syntax-dynamic-import \
    eslint eslint-loader \
    file-loader html-withimg-loader url-loader \
    clean-webpack-plugin \
    happypack \
    
    webpack-dev-server -D
}

base_config(){
    cat <<-EOF > webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MinCssExtractPlugin = require('mini-css-extract-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const serverConfig = require('./server.js')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')


const merge = (isUse , conf) => {
    if(isUse === false) {
        return []
    }
    return [conf]
}

const arr2obj = (arr , visitFunc) => {
    let r = {}
    arr.forEach(v => {
        r[v] = visitFunc(v)
    })
    return r
}

const Webpack = require('webpack')
module.exports = {
    devServer :{
        port : serverConfig.port,
        progress: true,
        contentBase : $(echo '`./${serverConfig.path}`'),
        //open : true,
        compress : true,
        proxy: serverConfig.proxy,
    },
    mode : process.env.ENV,
    // [index] => {index : './src/index.js'}
    entry : arr2obj(serverConfig.entry,v => $(echo '`./src/${v}.js`')),
    devtool : 'eval-source-map',
    resolve : serverConfig.resolve,
    output : {
        filename : '[name].[hash:8].js',
        path: path.resolve(__dirname,serverConfig.path),
        publicPath: serverConfig.publicPath
    },
    plugins:[
        ...serverConfig.entry.map(v => new HtmlWebpackPlugin({
            template : $(echo '`./src/${v}.html`'),
            filename : $(echo '`${v}.html`'),
            minify:{
                removeAttributeQuotes:true,
                collapseInlineTagWhitespace:true,
            },
            chunks: [v],
        })),
        new MinCssExtractPlugin({
            filename : 'css/[name].[hash:10].css'
        }),
        new Webpack.ProvidePlugin({
            // $ : 'jquery'
        }),
        new Webpack.DefinePlugin({
            ENV : JSON.stringify(process.env.ENV)
        }),
        new CleanWebpackPlugin()
    ],
    externals : { // 不需要打包的模块
        jquery : '$'
    },
    resolve: serverConfig.resolve,
    module : {
        rules:[
            ...merge(serverConfig.eslint,{
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader:'eslint-loader',
                    options :{
                        enforce : 'pre'
                    }
                },
            }),
            {
                test: /\.(htm|html)$/i,
                loader: 'html-withimg-loader'
            },
            {
                test : /\.(png|jp?g|gif|svg)$/i,
                use: [
                    {
                      loader: 'url-loader',
                      options: {
                        outputPath: 'images',
                        limit: 8192,
                      },
                    },
                  ],
            },
            {
                test: /\.js$/,
                exclude: /(node_modules|bower_components)/,
                include:path.resolve(__dirname,'src'),
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: [
                            '@babel/preset-env',$(reactOnly $1 "'@babel/preset-react'")
                        ],
                        plugins:[
                            ['@babel/plugin-proposal-decorators',{legacy:true}],
                            ['@babel/plugin-proposal-class-properties',{loose : true}],
                            '@babel/plugin-transform-runtime',
                        ]
                    }
                }
            },
            {
                test: /\.css$/,
                use:[MinCssExtractPlugin.loader,'css-loader','postcss-loader']
            },
            {
                test : /\.less$/,
                use : [MinCssExtractPlugin.loader,'css-loader','postcss-loader','less-loader'],
            }
        ]
    },
    optimization:{
        minimizer:[
            new UglifyJsPlugin({
                cache:true,
                parallel : true,
                sourceMap : true,
            }),
            new OptimizeCSSAssetsPlugin(),
        ]
    }
}
EOF
}

react_dll(){

}

_install_react(){
    cnpm install @babel/preset-react -D
    cnpm install --save react react-dom
    base_config react
}

install_react(){
    install_webpack
    _install_react
}

$*



